Completed
Push — master ( 8967bc...e88c19 )
by Rain
02:47
created

User.js ➔ ???   A

Complexity

Conditions 1

Size

Total Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 42
Bugs 0 Features 0
Metric Value
cc 1
c 42
b 0
f 0
dl 0
loc 59
rs 9.597

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
2
import window from 'window';
3
import _ from '_';
4
import $ from '$';
5
import progressJs from 'progressJs';
6
import Tinycon from 'Tinycon';
7
8
import {
9
	noop, trim, log, has, isArray, inArray, isUnd, isNormal, isPosNumeric, isNonEmptyArray,
10
	pInt, pString, delegateRunOnDestroy, mailToHelper, windowResize
11
} from 'Common/Utils';
12
13
import {
14
	Layout, Capa, StorageResultType, Notification, FolderType,
15
	SetSystemFoldersNotification, MessageSetAction, ClientSideKeyName
16
} from 'Common/Enums';
17
18
import {
19
	$html,
20
	leftPanelWidth, leftPanelDisabled,
21
	bAnimationSupported, bMobileDevice
22
} from 'Common/Globals';
23
24
import {UNUSED_OPTION_VALUE} from 'Common/Consts';
25
import * as Plugins from 'Common/Plugins';
26
import * as Links from 'Common/Links';
27
import * as Events from 'Common/Events';
28
import * as Momentor from 'Common/Momentor';
29
import * as Cache from 'Common/Cache';
30
import {getNotification, i18n} from 'Common/Translator';
31
32
import SocialStore from 'Stores/Social';
33
import SettingsStore from 'Stores/User/Settings';
34
import AccountStore from 'Stores/User/Account';
35
import IdentityStore from 'Stores/User/Identity';
36
import TemplateStore from 'Stores/User/Template';
37
import FolderStore from 'Stores/User/Folder';
38
import PgpStore from 'Stores/User/Pgp';
39
import MessageStore from 'Stores/User/Message';
40
import ContactStore from 'Stores/User/Contact';
41
42
import * as Local from 'Storage/Client';
43
import * as Settings from 'Storage/Settings';
44
import {checkTimestamp} from 'Storage/RainLoop';
45
46
import Remote from 'Remote/User/Ajax';
47
import Promises from 'Promises/User/Ajax';
48
49
import {EmailModel} from 'Model/Email';
50
import {AccountModel} from 'Model/Account';
51
import {IdentityModel} from 'Model/Identity';
52
import {TemplateModel} from 'Model/Template';
53
import {OpenPgpKeyModel} from 'Model/OpenPgpKey';
54
55
// import {AboutUserScreen} from 'Screen/User/About';
56
import {LoginUserScreen} from 'Screen/User/Login';
57
import {MailBoxUserScreen} from 'Screen/User/MailBox';
58
import {SettingsUserScreen} from 'Screen/User/Settings';
59
60
import {
61
	hideLoading, routeOff, routeOn, setHash,
62
	startScreens, showScreenPopup
63
} from 'Knoin/Knoin';
64
65
import {AbstractApp} from 'App/Abstract';
66
67
class AppUser extends AbstractApp
68
{
69
	constructor() {
70
		super(Remote);
71
72
		this.moveCache = {};
73
74
		this.quotaDebounce = _.debounce(this.quota, 1000 * 30);
75
		this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this);
76
77
		this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500);
78
79
		window.setInterval(() => Events.pub('interval.30s'), 30000);
80
		window.setInterval(() => Events.pub('interval.1m'), 60000);
81
		window.setInterval(() => Events.pub('interval.2m'), 60000 * 2);
82
		window.setInterval(() => Events.pub('interval.3m'), 60000 * 3);
83
		window.setInterval(() => Events.pub('interval.5m'), 60000 * 5);
84
		window.setInterval(() => Events.pub('interval.10m'), 60000 * 10);
85
		window.setInterval(() => Events.pub('interval.15m'), 60000 * 15);
86
		window.setInterval(() => Events.pub('interval.20m'), 60000 * 15);
87
88
		window.setTimeout(() => window.setInterval(() => Events.pub('interval.2m-after5m'), 60000 * 2), 60000 * 5);
89
		window.setTimeout(() =>	window.setInterval(() => Events.pub('interval.5m-after5m'), 60000 * 5), 60000 * 5);
90
		window.setTimeout(() => window.setInterval(() => Events.pub('interval.10m-after5m'), 60000 * 10), 60000 * 5);
91
92
		$.wakeUp(() => {
93
			if (checkTimestamp())
94
			{
95
				this.reload();
96
			}
97
98
			Remote.jsVersion((sResult, oData) => {
99
				if (StorageResultType.Success === sResult && oData && !oData.Result)
100
				{
101
					this.reload();
102
				}
103
			}, Settings.appSettingsGet('version'));
104
105
		}, {}, 60 * 60 * 1000);
106
107
		if (checkTimestamp())
108
		{
109
			this.reload();
110
		}
111
112
		if (Settings.settingsGet('UserBackgroundHash'))
113
		{
114
			_.delay(() => {
115
				$('#rl-bg')
116
					.attr('style', 'background-image: none !important;')
117
					.backstretch(Links.userBackground(Settings.settingsGet('UserBackgroundHash')), {
118
						fade: bAnimationSupported ? 1000 : 0,
119
						centeredX: true,
120
						centeredY: true
121
					})
122
					.removeAttr('style');
123
			}, 1000);
124
		}
125
126
		this.socialUsers = _.bind(this.socialUsers, this);
127
	}
128
129
	remote() {
130
		return Remote;
131
	}
132
133
	reload() {
134
		if (window.parent && !!Settings.appSettingsGet('inIframe'))
135
		{
136
			window.parent.location.reload();
137
		}
138
		else
139
		{
140
			window.location.reload();
141
		}
142
	}
143
144
	reloadFlagsCurrentMessageListAndMessageFromCache() {
145
		_.each(MessageStore.messageList(), (message) => {
146
			Cache.initMessageFlagsFromCache(message);
147
		});
148
		Cache.initMessageFlagsFromCache(MessageStore.message());
149
	}
150
151
	/**
152
	 * @param {boolean=} bDropPagePosition = false
153
	 * @param {boolean=} bDropCurrenFolderCache = false
154
	 */
155
	reloadMessageList(bDropPagePosition = false, bDropCurrenFolderCache = false) {
156
157
		let
158
			iOffset = (MessageStore.messageListPage() - 1) * SettingsStore.messagesPerPage();
159
160
		if (bDropCurrenFolderCache)
161
		{
162
			Cache.setFolderHash(FolderStore.currentFolderFullNameRaw(), '');
163
		}
164
165
		if (bDropPagePosition)
166
		{
167
			MessageStore.messageListPage(1);
168
			MessageStore.messageListPageBeforeThread(1);
169
			iOffset = 0;
170
171
			setHash(Links.mailBox(
172
				FolderStore.currentFolderFullNameHash(),
173
				MessageStore.messageListPage(),
174
				MessageStore.messageListSearch(),
175
				MessageStore.messageListThreadUid()
176
			), true, true);
177
		}
178
179
		MessageStore.messageListLoading(true);
180
		Remote.messageList((sResult, oData, bCached) => {
181
182
			if (StorageResultType.Success === sResult && oData && oData.Result)
183
			{
184
				MessageStore.messageListError('');
185
				MessageStore.messageListLoading(false);
186
187
				MessageStore.setMessageList(oData, bCached);
188
			}
189
			else if (StorageResultType.Unload === sResult)
190
			{
191
				MessageStore.messageListError('');
192
				MessageStore.messageListLoading(false);
193
			}
194
			else if (StorageResultType.Abort !== sResult)
195
			{
196
				MessageStore.messageList([]);
197
				MessageStore.messageListLoading(false);
198
				MessageStore.messageListError(oData && oData.ErrorCode ?
199
					getNotification(oData.ErrorCode) : i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST')
200
				);
201
			}
202
203
		}, FolderStore.currentFolderFullNameRaw(), iOffset, SettingsStore.messagesPerPage(),
204
			MessageStore.messageListSearch(), MessageStore.messageListThreadUid());
205
	}
206
207
	recacheInboxMessageList() {
208
		Remote.messageList(noop, Cache.getFolderInboxName(), 0, SettingsStore.messagesPerPage(), '', '', true);
209
	}
210
211
	/**
212
	 * @param {Function} fResultFunc
213
	 * @returns {boolean}
214
	 */
215
	contactsSync(fResultFunc) {
216
217
		const oContacts = ContactStore.contacts;
218
		if (oContacts.importing() || oContacts.syncing() || !ContactStore.enableContactsSync() || !ContactStore.allowContactsSync())
219
		{
220
			return false;
221
		}
222
223
		oContacts.syncing(true);
224
225
		Remote.contactsSync((sResult, oData) => {
226
227
			oContacts.syncing(false);
228
229
			if (fResultFunc)
230
			{
231
				fResultFunc(sResult, oData);
232
			}
233
		});
234
235
		return true;
236
	}
237
238
	messagesMoveTrigger() {
239
240
		const
241
			sTrashFolder = FolderStore.trashFolder(),
242
			sSpamFolder = FolderStore.spamFolder();
243
244
		_.each(this.moveCache, (oItem) => {
245
246
			var
247
				bSpam = sSpamFolder === oItem.To,
248
				bTrash = sTrashFolder === oItem.To,
249
				bHam = !bSpam && sSpamFolder === oItem.From && Cache.getFolderInboxName() === oItem.To;
250
251
			Remote.messagesMove(this.moveOrDeleteResponseHelper, oItem.From, oItem.To, oItem.Uid,
252
				bSpam ? 'SPAM' : (bHam ? 'HAM' : ''), bSpam || bTrash);
253
		});
254
255
		this.moveCache = {};
256
	}
257
258
	messagesMoveHelper(sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForMove) {
259
260
		var sH = '$$' + sFromFolderFullNameRaw + '$$' + sToFolderFullNameRaw + '$$';
261
		if (!this.moveCache[sH])
262
		{
263
			this.moveCache[sH] = {
264
				From: sFromFolderFullNameRaw,
265
				To: sToFolderFullNameRaw,
266
				Uid: []
267
			};
268
		}
269
270
		this.moveCache[sH].Uid = _.union(this.moveCache[sH].Uid, aUidForMove);
271
		this.messagesMoveTrigger();
272
	}
273
274
	messagesCopyHelper(sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForCopy) {
275
		Remote.messagesCopy(
276
			this.moveOrDeleteResponseHelper,
277
			sFromFolderFullNameRaw,
278
			sToFolderFullNameRaw,
279
			aUidForCopy
280
		);
281
	}
282
283
	messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove) {
284
		Remote.messagesDelete(
285
			this.moveOrDeleteResponseHelper,
286
			sFromFolderFullNameRaw,
287
			aUidForRemove
288
		);
289
	}
290
291
	moveOrDeleteResponseHelper(sResult, oData) {
292
293
		if (StorageResultType.Success === sResult && FolderStore.currentFolder())
294
		{
295
			if (oData && isArray(oData.Result) && 2 === oData.Result.length)
296
			{
297
				Cache.setFolderHash(oData.Result[0], oData.Result[1]);
298
			}
299
			else
300
			{
301
				Cache.setFolderHash(FolderStore.currentFolderFullNameRaw(), '');
302
303
				if (oData && -1 < inArray(oData.ErrorCode,
304
					[Notification.CantMoveMessage, Notification.CantCopyMessage]))
305
				{
306
					window.alert(getNotification(oData.ErrorCode));
307
				}
308
			}
309
310
			this.reloadMessageList(0 === MessageStore.messageList().length);
311
			this.quotaDebounce();
312
		}
313
	}
314
315
	/**
316
	 * @param {string} sFromFolderFullNameRaw
317
	 * @param {Array} aUidForRemove
318
	 */
319
	deleteMessagesFromFolderWithoutCheck(sFromFolderFullNameRaw, aUidForRemove) {
320
		this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
321
		MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
322
	}
323
324
	/**
325
	 * @param {number} iDeleteType
326
	 * @param {string} sFromFolderFullNameRaw
327
	 * @param {Array} aUidForRemove
328
	 * @param {boolean=} bUseFolder = true
329
	 */
330
	deleteMessagesFromFolder(iDeleteType, sFromFolderFullNameRaw, aUidForRemove, bUseFolder) {
331
332
		let
333
			oMoveFolder = null,
0 ignored issues
show
Unused Code introduced by
The assignment to oMoveFolder seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
334
			nSetSystemFoldersNotification = null;
0 ignored issues
show
Unused Code introduced by
The assignment to nSetSystemFoldersNotification seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
335
336
		switch (iDeleteType)
337
		{
338
			case FolderType.Spam:
339
				oMoveFolder = Cache.getFolderFromCacheList(FolderStore.spamFolder());
340
				nSetSystemFoldersNotification = SetSystemFoldersNotification.Spam;
341
				break;
342
			case FolderType.NotSpam:
343
				oMoveFolder = Cache.getFolderFromCacheList(Cache.getFolderInboxName());
344
				break;
345
			case FolderType.Trash:
346
				oMoveFolder = Cache.getFolderFromCacheList(FolderStore.trashFolder());
347
				nSetSystemFoldersNotification = SetSystemFoldersNotification.Trash;
348
				break;
349
			case FolderType.Archive:
350
				oMoveFolder = Cache.getFolderFromCacheList(FolderStore.archiveFolder());
351
				nSetSystemFoldersNotification = SetSystemFoldersNotification.Archive;
352
				break;
353
			// no default
354
		}
355
356
		bUseFolder = isUnd(bUseFolder) ? true : !!bUseFolder;
357
		if (bUseFolder)
358
		{
359
			if ((FolderType.Spam === iDeleteType && UNUSED_OPTION_VALUE === FolderStore.spamFolder()) ||
360
				(FolderType.Trash === iDeleteType && UNUSED_OPTION_VALUE === FolderStore.trashFolder()) ||
361
				(FolderType.Archive === iDeleteType && UNUSED_OPTION_VALUE === FolderStore.archiveFolder()))
362
			{
363
				bUseFolder = false;
364
			}
365
		}
366
367
		if (!oMoveFolder && bUseFolder)
368
		{
369
			showScreenPopup(require('View/Popup/FolderSystem'), [nSetSystemFoldersNotification]);
370
		}
371
		else if (!bUseFolder || (FolderType.Trash === iDeleteType &&
372
			(sFromFolderFullNameRaw === FolderStore.spamFolder() || sFromFolderFullNameRaw === FolderStore.trashFolder())))
373
		{
374
			showScreenPopup(require('View/Popup/Ask'), [i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), () => {
375
				this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
376
				MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
377
			}]);
378
		}
379
		else if (oMoveFolder)
380
		{
381
			this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove);
382
			MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw);
383
		}
384
	}
385
386
	/**
387
	 * @param {string} sFromFolderFullNameRaw
388
	 * @param {Array} aUidForMove
389
	 * @param {string} sToFolderFullNameRaw
390
	 * @param {boolean=} bCopy = false
391
	 */
392
	moveMessagesToFolder(sFromFolderFullNameRaw, aUidForMove, sToFolderFullNameRaw, bCopy) {
393
394
		if (sFromFolderFullNameRaw !== sToFolderFullNameRaw && isArray(aUidForMove) && 0 < aUidForMove.length)
395
		{
396
			const
397
				oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
398
				oToFolder = Cache.getFolderFromCacheList(sToFolderFullNameRaw);
399
400
			if (oFromFolder && oToFolder)
401
			{
402
				if (isUnd(bCopy) ? false : !!bCopy)
403
				{
404
					this.messagesCopyHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove);
405
				}
406
				else
407
				{
408
					this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove);
409
				}
410
411
				MessageStore.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy);
412
				return true;
413
			}
414
		}
415
416
		return false;
417
	}
418
419
	/**
420
	 * @param {Function=} callback = null
421
	 */
422
	foldersReload(callback = null) {
423
		const prom = Promises.foldersReload(FolderStore.foldersLoading);
424
		if (callback)
425
		{
426
			prom.then((value) => {
427
				callback(!!value);
428
			}).catch(() => {
429
				_.delay(() => {
430
					callback(false);
431
				}, 1);
432
			});
433
		}
434
	}
435
436
	foldersPromisesActionHelper(promise, errorDefCode) {
437
438
		Promises
439
			.abort('Folders')
440
			.fastResolve(true)
441
			.then(() => promise)
442
			.then(() => {
443
				Promises.foldersReloadWithTimeout(FolderStore.foldersLoading);
444
			}, (errorCode) => {
445
				FolderStore.folderList.error(getNotification(errorCode, '', errorDefCode));
446
				Promises.foldersReloadWithTimeout(FolderStore.foldersLoading);
447
			});
448
	}
449
450
	reloadOpenPgpKeys() {
451
452
		if (PgpStore.capaOpenPGP())
453
		{
454
			var
455
				aKeys = [],
456
				oEmail = new EmailModel(),
457
				oOpenpgpKeyring = PgpStore.openpgpKeyring,
458
				oOpenpgpKeys = oOpenpgpKeyring ? oOpenpgpKeyring.getAllKeys() : [];
459
460
			_.each(oOpenpgpKeys, (oItem, iIndex) => {
461
				if (oItem && oItem.primaryKey)
462
				{
463
					var
464
						aEmails = [],
465
						aUsers = [],
466
						oPrimaryUser = oItem.getPrimaryUser(),
467
						sUser = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid :
468
							(oItem.users && oItem.users[0] ? oItem.users[0].userId.userid : '');
469
470
					if (oItem.users)
471
					{
472
						_.each(oItem.users, (item) => {
473
							if (item.userId)
474
							{
475
								oEmail.clear();
476
								oEmail.mailsoParse(item.userId.userid);
477
								if (oEmail.validate())
478
								{
479
									aEmails.push(oEmail.email);
480
									aUsers.push(item.userId.userid);
481
								}
482
							}
483
						});
484
					}
485
486
					if (aEmails.length)
487
					{
488
						aKeys.push(new OpenPgpKeyModel(
489
							iIndex,
490
							oItem.primaryKey.getFingerprint(),
491
							oItem.primaryKey.getKeyId().toHex().toLowerCase(),
492
							_.uniq(_.compact(_.map(
493
								oItem.getKeyIds(), (item) => (item && item.toHex ? item.toHex() : null)
0 ignored issues
show
introduced by
This code is unreachable and can thus be removed without consequences.
Loading history...
Bug introduced by
The variable item seems to be never initialized.
Loading history...
494
							))),
495
							aUsers,
496
							aEmails,
497
							oItem.isPrivate(),
498
							oItem.armor(),
499
							sUser)
500
						);
501
					}
502
				}
503
			});
504
505
			delegateRunOnDestroy(PgpStore.openpgpkeys());
506
			PgpStore.openpgpkeys(aKeys);
507
		}
508
	}
509
510
	accountsCounts() {
511
		return false;
512
//		AccountStore.accounts.loading(true);
513
//
514
//		Remote.accountsCounts((sResult, oData) => {
515
//
516
//			AccountStore.accounts.loading(false);
517
//
518
//			if (StorageResultType.Success === sResult && oData.Result && oData.Result['Counts'])
519
//			{
520
//				var
521
//					sEmail = AccountStore.email(),
522
//					aAcounts = AccountStore.accounts()
523
//				;
524
//
525
//				_.each(oData.Result['Counts'], (oItem) => {
526
//
527
//					var oAccount = _.find(aAcounts, (oAccount) => {
528
//						return oAccount && oItem[0] === oAccount.email && sEmail !== oAccount.email;
529
//					});
530
//
531
//					if (oAccount)
532
//					{
533
//						oAccount.count(pInt(oItem[1]));
534
//					}
535
//				});
536
//			}
537
//		});
538
	}
539
540
	accountsAndIdentities(bBoot) {
541
542
		AccountStore.accounts.loading(true);
543
		IdentityStore.identities.loading(true);
544
545
		Remote.accountsAndIdentities((sResult, oData) => {
546
547
			AccountStore.accounts.loading(false);
548
			IdentityStore.identities.loading(false);
549
550
			if (StorageResultType.Success === sResult && oData.Result)
551
			{
552
				var
553
					aCounts = {},
554
					sParentEmail = Settings.settingsGet('ParentEmail'),
555
					sAccountEmail = AccountStore.email();
556
557
				sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail;
558
559
				if (isArray(oData.Result.Accounts))
560
				{
561
					_.each(AccountStore.accounts(), (oAccount) => {
562
						aCounts[oAccount.email] = oAccount.count();
563
					});
564
565
					delegateRunOnDestroy(AccountStore.accounts());
566
567
					AccountStore.accounts(_.map(oData.Result.Accounts,
568
						(sValue) => new AccountModel(sValue, sValue !== sParentEmail, aCounts[sValue] || 0)));
569
				}
570
571
				if (isUnd(bBoot) ? false : !!bBoot)
572
				{
573
					_.delay(() => this.accountsCounts(), 1000 * 5);
574
					Events.sub('interval.10m-after5m', () => this.accountsCounts());
575
				}
576
577
				if (isArray(oData.Result.Identities))
578
				{
579
					delegateRunOnDestroy(IdentityStore.identities());
580
581
					IdentityStore.identities(_.map(oData.Result.Identities, (oIdentityData) => {
582
583
						const
584
							sId = pString(oIdentityData.Id),
585
							sEmail = pString(oIdentityData.Email),
586
							oIdentity = new IdentityModel(sId, sEmail);
587
588
						oIdentity.name(pString(oIdentityData.Name));
589
						oIdentity.replyTo(pString(oIdentityData.ReplyTo));
590
						oIdentity.bcc(pString(oIdentityData.Bcc));
591
						oIdentity.signature(pString(oIdentityData.Signature));
592
						oIdentity.signatureInsertBefore(!!oIdentityData.SignatureInsertBefore);
593
594
						return oIdentity;
595
					}));
596
				}
597
			}
598
		});
599
	}
600
601
	templates() {
602
603
		TemplateStore.templates.loading(true);
604
605
		Remote.templates((result, data) => {
606
607
			TemplateStore.templates.loading(false);
608
609
			if (StorageResultType.Success === result && data.Result &&
610
				isArray(data.Result.Templates))
611
			{
612
				delegateRunOnDestroy(TemplateStore.templates());
613
614
				TemplateStore.templates(_.compact(_.map(data.Result.Templates, (templateData) => {
615
					const template = new TemplateModel();
616
					return template.parse(templateData) ? template : null;
617
				})));
618
			}
619
		});
620
	}
621
622
	quota() {
623
		Remote.quota((result, data) => {
624
			if (StorageResultType.Success === result && data && data.Result &&
625
				isArray(data.Result) && 1 < data.Result.length &&
626
				isPosNumeric(data.Result[0], true) && isPosNumeric(data.Result[1], true))
627
			{
628
				require('Stores/User/Quota').populateData(
629
					pInt(data.Result[1]), pInt(data.Result[0]));
630
			}
631
		});
632
	}
633
634
	/**
635
	 * @param {string} folder
636
	 * @param {Array=} list = []
637
	 */
638
	folderInformation(folder, list) {
639
		if ('' !== trim(folder))
640
		{
641
			Remote.folderInformation((result, data) => {
642
				if (StorageResultType.Success === result)
643
				{
644
					if (data && data.Result && data.Result.Hash && data.Result.Folder)
645
					{
646
						let
647
							uid = '',
648
							check = false,
649
							unreadCountChange = false;
650
651
						const folderFromCache = Cache.getFolderFromCacheList(data.Result.Folder);
652
						if (folderFromCache)
653
						{
654
							folderFromCache.interval = Momentor.momentNowUnix();
655
656
							if (data.Result.Hash)
657
							{
658
								Cache.setFolderHash(data.Result.Folder, data.Result.Hash);
659
							}
660
661
							if (isNormal(data.Result.MessageCount))
662
							{
663
								folderFromCache.messageCountAll(data.Result.MessageCount);
664
							}
665
666
							if (isNormal(data.Result.MessageUnseenCount))
667
							{
668
								if (pInt(folderFromCache.messageCountUnread()) !== pInt(data.Result.MessageUnseenCount))
669
								{
670
									unreadCountChange = true;
671
								}
672
673
								folderFromCache.messageCountUnread(data.Result.MessageUnseenCount);
674
							}
675
676
							if (unreadCountChange)
677
							{
678
								Cache.clearMessageFlagsFromCacheByFolder(folderFromCache.fullNameRaw);
679
							}
680
681
							if (data.Result.Flags)
682
							{
683
								for (uid in data.Result.Flags)
684
								{
685
									if (has(data.Result.Flags, uid))
686
									{
687
										check = true;
688
										const flags = data.Result.Flags[uid];
689
										Cache.storeMessageFlagsToCacheByFolderAndUid(folderFromCache.fullNameRaw, uid.toString(), [
690
											!flags.IsSeen, !!flags.IsFlagged, !!flags.IsAnswered, !!flags.IsForwarded, !!flags.IsReadReceipt
691
										]);
692
									}
693
								}
694
695
								if (check)
696
								{
697
									this.reloadFlagsCurrentMessageListAndMessageFromCache();
698
								}
699
							}
700
701
							MessageStore.initUidNextAndNewMessages(folderFromCache.fullNameRaw, data.Result.UidNext, data.Result.NewMessages);
702
703
							const hash = Cache.getFolderHash(data.Result.Folder);
704
							if (data.Result.Hash !== hash || '' === hash || unreadCountChange)
705
							{
706
								if (folderFromCache.fullNameRaw === FolderStore.currentFolderFullNameRaw())
707
								{
708
									this.reloadMessageList();
709
								}
710
								else if (Cache.getFolderInboxName() === folderFromCache.fullNameRaw)
711
								{
712
									this.recacheInboxMessageList();
713
								}
714
							}
715
						}
716
					}
717
				}
718
			}, folder, list);
719
		}
720
	}
721
722
	/**
723
	 * @param {boolean=} boot = false
724
	 */
725
	folderInformationMultiply(boot = false) {
726
727
		const folders = FolderStore.getNextFolderNames();
728
		if (isNonEmptyArray(folders))
729
		{
730
			Remote.folderInformationMultiply((sResult, oData) => {
731
				if (StorageResultType.Success === sResult)
732
				{
733
					if (oData && oData.Result && oData.Result.List && isNonEmptyArray(oData.Result.List))
734
					{
735
						const utc = Momentor.momentNowUnix();
736
						_.each(oData.Result.List, (oItem) => {
737
738
							var
739
								sHash = Cache.getFolderHash(oItem.Folder),
740
								oFolder = Cache.getFolderFromCacheList(oItem.Folder),
741
								bUnreadCountChange = false;
742
743
							if (oFolder)
744
							{
745
								oFolder.interval = utc;
746
747
								if (oItem.Hash)
748
								{
749
									Cache.setFolderHash(oItem.Folder, oItem.Hash);
750
								}
751
752
								if (isNormal(oItem.MessageCount))
753
								{
754
									oFolder.messageCountAll(oItem.MessageCount);
755
								}
756
757
								if (isNormal(oItem.MessageUnseenCount))
758
								{
759
									if (pInt(oFolder.messageCountUnread()) !== pInt(oItem.MessageUnseenCount))
760
									{
761
										bUnreadCountChange = true;
762
									}
763
764
									oFolder.messageCountUnread(oItem.MessageUnseenCount);
765
								}
766
767
								if (bUnreadCountChange)
768
								{
769
									Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
770
								}
771
772
								if (oItem.Hash !== sHash || '' === sHash)
773
								{
774
									if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
775
									{
776
										this.reloadMessageList();
777
									}
778
								}
779
								else if (bUnreadCountChange)
780
								{
781
									if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw())
782
									{
783
										const aList = MessageStore.messageList();
784
										if (isNonEmptyArray(aList))
785
										{
786
											this.folderInformation(oFolder.fullNameRaw, aList);
787
										}
788
									}
789
								}
790
							}
791
						});
792
793
						if (boot)
794
						{
795
							_.delay(() => this.folderInformationMultiply(true), 2000);
796
						}
797
					}
798
				}
799
			}, folders);
800
		}
801
	}
802
803
	/**
804
	 * @param {string} sFolderFullNameRaw
805
	 * @param {string|bool} mUid
806
	 * @param {number} iSetAction
807
	 * @param {Array=} aMessages = null
808
	 */
809
	messageListAction(sFolderFullNameRaw, mUid, iSetAction, aMessages) {
810
811
		var
812
			oFolder = null,
0 ignored issues
show
Unused Code introduced by
The assignment to oFolder seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
813
			aRootUids = [],
0 ignored issues
show
Unused Code introduced by
The assignment to variable aRootUids seems to be never used. Consider removing it.
Loading history...
814
			iAlreadyUnread = 0;
815
816
		if (isUnd(aMessages))
817
		{
818
			aMessages = MessageStore.messageListChecked();
819
		}
820
821
		aRootUids = _.uniq(_.compact(_.map(aMessages, (oMessage) => (oMessage && oMessage.uid ? oMessage.uid : null))));
822
823
		if ('' !== sFolderFullNameRaw && 0 < aRootUids.length)
824
		{
825
			switch (iSetAction)
826
			{
827
				case MessageSetAction.SetSeen:
828
829
					_.each(aRootUids, (sSubUid) => {
830
						iAlreadyUnread += Cache.storeMessageFlagsToCacheBySetAction(
831
							sFolderFullNameRaw, sSubUid, iSetAction);
832
					});
833
834
					oFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);
835
					if (oFolder)
836
					{
837
						oFolder.messageCountUnread(oFolder.messageCountUnread() - iAlreadyUnread);
838
					}
839
840
					Remote.messageSetSeen(noop, sFolderFullNameRaw, aRootUids, true);
841
					break;
842
843
				case MessageSetAction.UnsetSeen:
844
845
					_.each(aRootUids, (sSubUid) => {
846
						iAlreadyUnread += Cache.storeMessageFlagsToCacheBySetAction(
847
							sFolderFullNameRaw, sSubUid, iSetAction);
848
					});
849
850
					oFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);
851
					if (oFolder)
852
					{
853
						oFolder.messageCountUnread(oFolder.messageCountUnread() - iAlreadyUnread + aRootUids.length);
854
					}
855
856
					Remote.messageSetSeen(noop, sFolderFullNameRaw, aRootUids, false);
857
					break;
858
859
				case MessageSetAction.SetFlag:
860
861
					_.each(aRootUids, (sSubUid) => {
862
						Cache.storeMessageFlagsToCacheBySetAction(
863
							sFolderFullNameRaw, sSubUid, iSetAction);
864
					});
865
866
					Remote.messageSetFlagged(noop, sFolderFullNameRaw, aRootUids, true);
867
					break;
868
869
				case MessageSetAction.UnsetFlag:
870
871
					_.each(aRootUids, (sSubUid) => {
872
						Cache.storeMessageFlagsToCacheBySetAction(
873
							sFolderFullNameRaw, sSubUid, iSetAction);
874
					});
875
876
					Remote.messageSetFlagged(noop, sFolderFullNameRaw, aRootUids, false);
877
					break;
878
				// no default
879
			}
880
881
			this.reloadFlagsCurrentMessageListAndMessageFromCache();
882
			MessageStore.message.viewTrigger(!MessageStore.message.viewTrigger());
883
		}
884
	}
885
886
	googleConnect() {
887
		window.open(Links.socialGoogle(), 'Google', 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes');
888
	}
889
890
	twitterConnect() {
891
		window.open(Links.socialTwitter(), 'Twitter', 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes');
892
	}
893
894
	facebookConnect() {
895
		window.open(Links.socialFacebook(), 'Facebook', 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes');
896
	}
897
898
	/**
899
	 * @param {boolean=} fireAllActions = false
900
	 */
901
	socialUsers(fireAllActions = false) {
902
		if (true === fireAllActions)
903
		{
904
			SocialStore.google.loading(true);
905
			SocialStore.facebook.loading(true);
906
			SocialStore.twitter.loading(true);
907
		}
908
909
		Remote.socialUsers((result, data) => {
910
911
			if (StorageResultType.Success === result && data && data.Result)
912
			{
913
				SocialStore.google.userName(data.Result.Google || '');
914
				SocialStore.facebook.userName(data.Result.Facebook || '');
915
				SocialStore.twitter.userName(data.Result.Twitter || '');
916
			}
917
			else
918
			{
919
				SocialStore.google.userName('');
920
				SocialStore.facebook.userName('');
921
				SocialStore.twitter.userName('');
922
			}
923
924
			SocialStore.google.loading(false);
925
			SocialStore.facebook.loading(false);
926
			SocialStore.twitter.loading(false);
927
		});
928
	}
929
930
	googleDisconnect() {
931
		SocialStore.google.loading(true);
932
		Remote.googleDisconnect(this.socialUsers);
933
	}
934
935
	facebookDisconnect() {
936
		SocialStore.facebook.loading(true);
937
		Remote.facebookDisconnect(this.socialUsers);
938
	}
939
940
	twitterDisconnect() {
941
		SocialStore.twitter.loading(true);
942
		Remote.twitterDisconnect(this.socialUsers);
943
	}
944
945
	/**
946
	 * @param {string} query
947
	 * @param {Function} autocompleteCallback
948
	 */
949
	getAutocomplete(query, autocompleteCallback) {
950
		Remote.suggestions((result, data) => {
951
			if (StorageResultType.Success === result && data && isArray(data.Result))
952
			{
953
				autocompleteCallback(_.compact(_.map(data.Result, (item) => (item && item[0] ? new EmailModel(item[0], item[1]) : null))));
0 ignored issues
show
introduced by
This code is unreachable and can thus be removed without consequences.
Loading history...
Bug introduced by
The variable item seems to be never initialized.
Loading history...
954
			}
955
			else if (StorageResultType.Abort !== result)
956
			{
957
				autocompleteCallback([]);
958
			}
959
		}, query);
960
	}
961
962
	/**
963
	 * @param {string} sFullNameHash
964
	 * @param {boolean} bExpanded
965
	 */
966
	setExpandedFolder(sFullNameHash, bExpanded) {
967
		let aExpandedList = Local.get(ClientSideKeyName.ExpandedFolders);
968
		if (!isArray(aExpandedList))
969
		{
970
			aExpandedList = [];
971
		}
972
973
		if (bExpanded)
974
		{
975
			aExpandedList.push(sFullNameHash);
976
			aExpandedList = _.uniq(aExpandedList);
977
		}
978
		else
979
		{
980
			aExpandedList = _.without(aExpandedList, sFullNameHash);
981
		}
982
983
		Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList);
984
	}
985
986
	initHorizontalLayoutResizer(sClientSideKeyName) {
987
988
		var
989
			iMinHeight = 200,
990
			iMaxHeight = 500,
991
			oTop = null,
992
			oBottom = null,
993
994
			fSetHeight = (height) => {
995
				if (height)
996
				{
997
					if (oTop)
998
					{
999
						oTop.attr('style', 'height:' + height + 'px');
1000
					}
1001
1002
					if (oBottom)
1003
					{
1004
						oBottom.attr('style', 'top:' + (55 /* top toolbar */ + height) + 'px');
1005
					}
1006
				}
1007
			},
1008
1009
			fResizeCreateFunction = (event) => {
1010
				if (event && event.target)
1011
				{
1012
					var oResizableHandle = $(event.target).find('.ui-resizable-handle');
1013
1014
					oResizableHandle
1015
						.on('mousedown', () => {
1016
							$html.addClass('rl-resizer');
1017
						})
1018
						.on('mouseup', () => {
1019
							$html.removeClass('rl-resizer');
1020
						});
1021
				}
1022
			},
1023
1024
			fResizeStartFunction = () => {
1025
				$html.addClass('rl-resizer');
1026
			},
1027
1028
			fResizeResizeFunction = _.debounce(() => {
1029
				$html.addClass('rl-resizer');
1030
			}, 500, true),
1031
1032
			fResizeStopFunction = (oEvent, oObject) => {
1033
				$html.removeClass('rl-resizer');
1034
				if (oObject && oObject.size && oObject.size.height)
1035
				{
1036
					Local.set(sClientSideKeyName, oObject.size.height);
1037
1038
					fSetHeight(oObject.size.height);
1039
1040
					windowResize();
1041
				}
1042
			},
1043
1044
			oOptions = {
1045
				helper: 'ui-resizable-helper-h',
1046
				minHeight: iMinHeight,
1047
				maxHeight: iMaxHeight,
1048
				handles: 's',
1049
				create: fResizeCreateFunction,
1050
				resize: fResizeResizeFunction,
1051
				start: fResizeStartFunction,
1052
				stop: fResizeStopFunction
1053
			},
1054
1055
			fDisable = (bDisable) => {
1056
				if (bDisable)
1057
				{
1058
					if (oTop && oTop.hasClass('ui-resizable'))
1059
					{
1060
						oTop
1061
							.resizable('destroy')
1062
							.removeAttr('style');
1063
					}
1064
1065
					if (oBottom)
1066
					{
1067
						oBottom.removeAttr('style');
1068
					}
1069
				}
1070
				else if ($html.hasClass('rl-bottom-preview-pane'))
1071
				{
1072
					oTop = $('.b-message-list-wrapper');
1073
					oBottom = $('.b-message-view-wrapper');
1074
1075
					if (!oTop.hasClass('ui-resizable'))
1076
					{
1077
						oTop.resizable(oOptions);
1078
					}
1079
1080
					const iHeight = pInt(Local.get(sClientSideKeyName)) || 300;
1081
					fSetHeight(iHeight > iMinHeight ? iHeight : iMinHeight);
1082
				}
1083
			};
1084
1085
		fDisable(false);
1086
1087
		Events.sub('layout', (layout) => {
1088
			fDisable(Layout.BottomPreview !== layout);
1089
		});
1090
	}
1091
1092
	initVerticalLayoutResizer(sClientSideKeyName) {
1093
1094
		var
1095
			iDisabledWidth = 60,
1096
			iMinWidth = 155,
1097
			oLeft = $('#rl-left'),
1098
			oRight = $('#rl-right'),
1099
1100
			mLeftWidth = Local.get(sClientSideKeyName) || null,
1101
1102
			fSetWidth = (iWidth) => {
1103
				if (iWidth)
1104
				{
1105
					leftPanelWidth(iWidth);
1106
1107
					$html.removeClass('rl-resizer');
1108
1109
					oLeft.css({
1110
						width: '' + iWidth + 'px'
1111
					});
1112
1113
					oRight.css({
1114
						left: '' + iWidth + 'px'
1115
					});
1116
				}
1117
			},
1118
1119
			fDisable = (bDisable) => {
1120
				if (bDisable)
1121
				{
1122
					oLeft.resizable('disable');
1123
					fSetWidth(iDisabledWidth);
1124
				}
1125
				else
1126
				{
1127
					oLeft.resizable('enable');
1128
					var iWidth = pInt(Local.get(sClientSideKeyName)) || iMinWidth;
1129
					fSetWidth(iWidth > iMinWidth ? iWidth : iMinWidth);
1130
				}
1131
			},
1132
1133
			fResizeCreateFunction = (oEvent) => {
1134
				if (oEvent && oEvent.target)
1135
				{
1136
					$(oEvent.target).find('.ui-resizable-handle')
1137
						.on('mousedown', () => {
1138
							$html.addClass('rl-resizer');
1139
						})
1140
						.on('mouseup', () => {
1141
							$html.removeClass('rl-resizer');
1142
						});
1143
				}
1144
			},
1145
			fResizeResizeFunction = _.debounce(() => {
1146
				$html.addClass('rl-resizer');
1147
			}, 500, true),
1148
			fResizeStartFunction = () => {
1149
				$html.addClass('rl-resizer');
1150
			},
1151
			fResizeStopFunction = (oEvent, oObject) => {
1152
				$html.removeClass('rl-resizer');
1153
				if (oObject && oObject.size && oObject.size.width)
1154
				{
1155
					Local.set(sClientSideKeyName, oObject.size.width);
1156
1157
					leftPanelWidth(oObject.size.width);
1158
1159
					oRight.css({
1160
						left: '' + oObject.size.width + 'px'
1161
					});
1162
1163
					oLeft.css({
1164
						position: '',
1165
						top: '',
1166
						left: '',
1167
						height: ''
1168
					});
1169
				}
1170
			};
1171
1172
		if (null !== mLeftWidth)
1173
		{
1174
			fSetWidth(mLeftWidth > iMinWidth ? mLeftWidth : iMinWidth);
1175
		}
1176
1177
		oLeft.resizable({
1178
			helper: 'ui-resizable-helper-w',
1179
			minWidth: iMinWidth,
1180
			maxWidth: 350,
1181
			handles: 'e',
1182
			create: fResizeCreateFunction,
1183
			resize: fResizeResizeFunction,
1184
			start: fResizeStartFunction,
1185
			stop: fResizeStopFunction
1186
		});
1187
1188
		Events.sub('left-panel.off', () => {
1189
			fDisable(true);
1190
		});
1191
1192
		Events.sub('left-panel.on', () => {
1193
			fDisable(false);
1194
		});
1195
	}
1196
1197
	logout() {
1198
		Remote.logout(() => {
1199
			this.loginAndLogoutReload(false, true,
1200
				Settings.settingsGet('ParentEmail') && 0 < Settings.settingsGet('ParentEmail').length);
1201
		});
1202
	}
1203
1204
	bootstartTwoFactorScreen() {
1205
		showScreenPopup(require('View/Popup/TwoFactorConfiguration'), [true]);
1206
	}
1207
1208
	bootstartWelcomePopup(url) {
1209
		showScreenPopup(require('View/Popup/WelcomePage'), [url]);
1210
	}
1211
1212
	bootstartLoginScreen() {
1213
1214
		$html.removeClass('rl-user-auth').addClass('rl-user-no-auth');
1215
1216
		const customLoginLink = pString(Settings.appSettingsGet('customLoginLink'));
1217
		if (!customLoginLink)
1218
		{
1219
			startScreens([
1220
				LoginUserScreen
1221
			]);
1222
1223
			Plugins.runHook('rl-start-login-screens');
1224
			Events.pub('rl.bootstart-login-screens');
1225
		}
1226
		else
1227
		{
1228
			routeOff();
1229
			setHash(Links.root(), true);
1230
			routeOff();
1231
1232
			_.defer(function() {
1233
				window.location.href = customLoginLink;
1234
			});
1235
		}
1236
	}
1237
1238
	bootend() {
1239
		if (progressJs)
1240
		{
1241
			progressJs.set(100).end();
1242
		}
1243
		hideLoading();
1244
	}
1245
1246
	bootstart() {
1247
1248
		super.bootstart();
1249
1250
		require('Stores/User/App').populate();
1251
		require('Stores/User/Settings').populate();
1252
		require('Stores/User/Notification').populate();
1253
		require('Stores/User/Account').populate();
1254
		require('Stores/User/Contact').populate();
1255
1256
		var
1257
			sJsHash = Settings.appSettingsGet('jsHash'),
1258
			sStartupUrl = pString(Settings.settingsGet('StartupUrl')),
1259
			iContactsSyncInterval = pInt(Settings.settingsGet('ContactsSyncInterval')),
1260
			bGoogle = Settings.settingsGet('AllowGoogleSocial'),
1261
			bFacebook = Settings.settingsGet('AllowFacebookSocial'),
1262
			bTwitter = Settings.settingsGet('AllowTwitterSocial');
1263
1264
		if (progressJs)
1265
		{
1266
			progressJs.set(90);
1267
		}
1268
1269
		leftPanelDisabled.subscribe((value) => {
1270
			Events.pub('left-panel.' + (value ? 'off' : 'on'));
1271
		});
1272
1273
		this.setWindowTitle('');
1274
		if (Settings.settingsGet('Auth'))
1275
		{
1276
			$html.addClass('rl-user-auth');
1277
1278
			if (Settings.capa(Capa.TwoFactor) &&
1279
				Settings.capa(Capa.TwoFactorForce) &&
1280
				Settings.settingsGet('RequireTwoFactor'))
1281
			{
1282
				this.bootend();
1283
				this.bootstartTwoFactorScreen();
1284
			}
1285
			else
1286
			{
1287
				this.setWindowTitle(i18n('TITLES/LOADING'));
1288
1289
// require.ensure([], function() { // require code splitting
1290
1291
				this.foldersReload((value) => {
1292
1293
					this.bootend();
1294
1295
					if (value)
1296
					{
1297
						if ('' !== sStartupUrl)
1298
						{
1299
							routeOff();
1300
							setHash(Links.root(sStartupUrl), true);
1301
							routeOn();
1302
						}
1303
1304
						if (window.jassl && window.crypto && window.crypto.getRandomValues && Settings.capa(Capa.OpenPGP))
1305
						{
1306
							const openpgpCallback = (openpgp) => {
1307
1308
								PgpStore.openpgp = openpgp;
1309
1310
								if (window.Worker)
1311
								{
1312
									try
1313
									{
1314
										PgpStore.openpgp.initWorker({path: Links.openPgpWorkerJs()});
1315
									}
1316
									catch (e)
1317
									{
1318
										log(e);
1319
									}
1320
								}
1321
1322
								PgpStore.openpgpKeyring = new openpgp.Keyring();
1323
								PgpStore.capaOpenPGP(true);
1324
1325
								Events.pub('openpgp.init');
1326
1327
								this.reloadOpenPgpKeys();
1328
							};
1329
1330
							if (window.openpgp)
1331
							{
1332
								openpgpCallback(window.openpgp);
1333
							}
1334
							else
1335
							{
1336
								window.jassl(Links.openPgpJs()).then(() => {
1337
									if (window.openpgp)
1338
									{
1339
										openpgpCallback(window.openpgp);
1340
									}
1341
								});
1342
							}
1343
						}
1344
						else
1345
						{
1346
							PgpStore.capaOpenPGP(false);
1347
						}
1348
1349
						startScreens([
1350
							MailBoxUserScreen,
1351
							Settings.capa(Capa.Settings) ? SettingsUserScreen : null
1352
//							false ? AboutUserScreen : null
1353
						]);
1354
1355
						if (bGoogle || bFacebook || bTwitter)
1356
						{
1357
							this.socialUsers(true);
1358
						}
1359
1360
						Events.sub('interval.2m', () => this.folderInformation(Cache.getFolderInboxName()));
1361
						Events.sub('interval.3m', () => {
1362
							const sF = FolderStore.currentFolderFullNameRaw();
1363
							if (Cache.getFolderInboxName() !== sF)
1364
							{
1365
								this.folderInformation(sF);
1366
							}
1367
						});
1368
1369
						Events.sub('interval.2m-after5m', () => this.folderInformationMultiply());
1370
						Events.sub('interval.15m', () => this.quota());
1371
						Events.sub('interval.20m', () => this.foldersReload());
1372
1373
						iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20;
1374
						iContactsSyncInterval = 320 >= iContactsSyncInterval ? iContactsSyncInterval : 320;
1375
1376
						_.delay(() => this.contactsSync(), 10000);
1377
						_.delay(() => this.folderInformationMultiply(true), 2000);
1378
1379
						window.setInterval(() => this.contactsSync(), iContactsSyncInterval * 60000 + 5000);
1380
1381
						this.accountsAndIdentities(true);
1382
1383
						_.delay(() => {
1384
							const sF = FolderStore.currentFolderFullNameRaw();
1385
							if (Cache.getFolderInboxName() !== sF)
1386
							{
1387
								this.folderInformation(sF);
1388
							}
1389
						}, 1000);
1390
1391
						_.delay(() => this.quota(), 5000);
1392
						_.delay(() => Remote.appDelayStart(noop), 35000);
1393
1394
						Events.sub('rl.auto-logout', () => this.logout());
1395
1396
						Plugins.runHook('rl-start-user-screens');
1397
						Events.pub('rl.bootstart-user-screens');
1398
1399
						if (Settings.settingsGet('WelcomePageUrl'))
1400
						{
1401
							_.delay(() => this.bootstartWelcomePopup(Settings.settingsGet('WelcomePageUrl')), 1000);
1402
						}
1403
1404
						if (!!Settings.settingsGet('AccountSignMe') &&
1405
							window.navigator.registerProtocolHandler &&
1406
							Settings.capa(Capa.Composer))
1407
						{
1408
							_.delay(() => {
1409
								try {
1410
									window.navigator.registerProtocolHandler('mailto',
1411
										window.location.protocol + '//' + window.location.host + window.location.pathname + '?mailto&to=%s',
1412
										'' + (Settings.settingsGet('Title') || 'RainLoop'));
1413
								}
1414
								catch (e) {} // eslint-disable-line no-empty
1415
1416
								if (Settings.settingsGet('MailToEmail'))
1417
								{
1418
									mailToHelper(Settings.settingsGet('MailToEmail'), require('View/Popup/Compose'));
1419
								}
1420
							}, 500);
1421
						}
1422
1423
						if (!bMobileDevice)
1424
						{
1425
							_.defer(() => this.initVerticalLayoutResizer(ClientSideKeyName.FolderListSize));
1426
1427
							if (Tinycon && Settings.appSettingsGet('faviconStatus') && !Settings.appSettingsGet('listPermanentFiltered'))
1428
							{
1429
								Tinycon.setOptions({
1430
									fallback: false
1431
								});
1432
1433
								Events.sub('mailbox.inbox-unread-count',
1434
									(iCount) => Tinycon.setBubble(0 < iCount ? (99 < iCount ? 99 : iCount) : 0));
1435
							}
1436
						}
1437
					}
1438
					else
1439
					{
1440
						this.logout();
1441
					}
1442
				});
1443
1444
// }); // require code splitting
1445
1446
			}
1447
		}
1448
		else
1449
		{
1450
			this.bootend();
1451
			this.bootstartLoginScreen();
1452
		}
1453
1454
		if (bGoogle)
1455
		{
1456
			window['rl_' + sJsHash + '_google_service'] = () => {
1457
				SocialStore.google.loading(true);
1458
				this.socialUsers();
1459
			};
1460
		}
1461
1462
		if (bFacebook)
1463
		{
1464
			window['rl_' + sJsHash + '_facebook_service'] = () => {
1465
				SocialStore.facebook.loading(true);
1466
				this.socialUsers();
1467
			};
1468
		}
1469
1470
		if (bTwitter)
1471
		{
1472
			window['rl_' + sJsHash + '_twitter_service'] = () => {
1473
				SocialStore.twitter.loading(true);
1474
				this.socialUsers();
1475
			};
1476
		}
1477
1478
		Events.sub('interval.1m', () => Momentor.reload());
1479
1480
		Plugins.runHook('rl-start-screens');
1481
		Events.pub('rl.bootstart-end');
1482
	}
1483
}
1484
1485
export default new AppUser();
1486